package com.code2roc.miniflow.base.model;

import com.code2roc.fastboot.framework.util.StringUtil;
import com.code2roc.miniflow.base.annotation.MiniFlowTable;
import com.code2roc.miniflow.base.util.MiniFlowJDBCUtil;
import com.code2roc.miniflow.base.util.MiniFlowReflectUtil;
import com.code2roc.miniflow.base.util.MiniFlowCommonUtil;

import java.util.Date;
import java.util.HashMap;
import java.util.List;

public class MiniFlowJDBCService<T extends MiniFlowBaseModel> {
    private Class tableClass;
    private String tableName;

    public MiniFlowJDBCService() {
        tableClass = getEntityClass();
        tableName = getTableName();
    }

    public void insert(T entity) {
        if (MiniFlowCommonUtil.isEmpty(entity.getRowguid())) {
            entity.setRowguid(MiniFlowCommonUtil.getNewGuid());
        }
        if (entity.getSort_num() == null) {
            entity.setSort_num(0);
        }
        entity.setGmt_create(new Date());
        entity.setGmt_modified(new Date());
        MiniFlowJDBCUtil.insert(entity);
    }

    public void delete(String rowguid) {
        HashMap<String, Object> paramMap = new HashMap<>();
        String sql = "delete from " + tableName + " where rowguid=#{rowguid}";
        paramMap.put("rowguid", rowguid);
        MiniFlowJDBCUtil.executeSQL(sql, paramMap);
    }

    public void deleteByField(String fieldName, Object filedValue) {
        HashMap<String, Object> paramMap = new HashMap<>();
        String sql = "delete from " + tableName + " where " + fieldName + "=#{" + fieldName + "}";
        paramMap.put(fieldName, filedValue);
        MiniFlowJDBCUtil.executeSQL(sql, paramMap);
    }

    public void update(T entity) {
        entity.setGmt_modified(new Date());
        MiniFlowJDBCUtil.update(entity);
    }

    public T selectOne(String rowguid) {
        List<T> dataList = selectListByField("rowguid", rowguid, "");
        if (dataList.size() == 0) {
            return null;
        } else {
            return dataList.get(0);
        }
    }

    public T selectOneByField(String fieldName, Object filedValue) {
        List<T> dataList = selectListByField(fieldName, filedValue, "");
        if (dataList.size() == 0) {
            return null;
        } else {
            return dataList.get(0);
        }
    }

    public List<T> selectPageList(String columns, String where, String orderBy, int pageIndex, int pageSize, HashMap<String, Object> paramMap) {
        return MiniFlowJDBCUtil.selectPageList(tableClass, getTableName(), columns, where, orderBy, pageIndex, pageSize, paramMap);
    }

    public List<T> selectList(String columns, String where, String orderBy, HashMap<String, Object> paramMap) {
        return MiniFlowJDBCUtil.selectList(tableClass, getTableName(), columns, where, orderBy, paramMap);
    }

    public List<T> selectListByField(String fieldName, Object filedValue, String orderBy) {
        HashMap<String, Object> paramMap = new HashMap<>();
        String sql = "" + fieldName + " = #{" + fieldName + "}";
        paramMap.put(fieldName, filedValue);
        return selectList("*", sql, orderBy, paramMap);
    }

    public int selectCount(String where, HashMap<String, Object> paramMap) {
        String sql = "select count(1) from " + tableName;
        if (!StringUtil.isEmpty(where)) {
            sql += " where " + where;
        }
        return MiniFlowCommonUtil.convert2Int(MiniFlowJDBCUtil.executeScar(sql, paramMap));
    }

    public Class getEntityClass() {
        return MiniFlowReflectUtil.getSuperClassGenricType(this.getClass());
    }

    private String getTableName() {
        Class<T> clazz = getEntityClass();
        String tabaleName = "";
        MiniFlowTable tableNameAnnotaion = (MiniFlowTable) clazz.getAnnotation(MiniFlowTable.class);
        if (tableNameAnnotaion != null) {
            tabaleName = tableNameAnnotaion.value();
        }
        return tabaleName;
    }
}
